package com.ruoyi.web.socket;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.model.MiniLoginUser;
import com.ruoyi.framework.security.context.UserContextHolder;
import com.ruoyi.system.domain.MyHistory;
import com.ruoyi.system.service.IMyHistoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.time.LocalDateTime;
import java.util.*;

/**
 * WebSocket服务
 */
@Slf4j
@Component
@ServerEndpoint("/ws/{uid}/{tid}/{identity}")
public class WebSocketServer {

    //存放会话对象
    private static Map<String, Session> sessionMap = new HashMap();
    private static IMyHistoryService myHistoryService;

    @Autowired
    public void setMyHistoryService(IMyHistoryService myHistoryService) {
        WebSocketServer.myHistoryService = myHistoryService;
    }

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("uid") String uid, @PathParam("tid") String tid, @PathParam("identity") String identity) {
        log.info("建立连接：" + uid + " " + tid + " " + identity);
        //查询历史记录
        MiniLoginUser currentUser = UserContextHolder.getCurrentUser();
        MyHistory myHistory = new MyHistory();
        myHistory.setTid(Long.parseLong(tid));
        myHistory.setUid(Long.parseLong(uid));
        myHistory.setChatType(identity.equals("u") ? 0 : 1);
        List<MyHistory> myHistories = myHistoryService.selectMyHistory(myHistory);

        if (identity.equals("u")) {
            sessionMap.put("u" + uid, session);
            sendToOne("u" + uid, JSON.toJSONString(myHistories));
        } else {
            sessionMap.put("t" + tid, session);
            sendToOne( "t" + tid, JSON.toJSONString(myHistories));
        }
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message, @PathParam("uid") String uid, @PathParam("tid") String tid, @PathParam("identity") String identity) {
        log.info("收到消息：" + uid + " " + tid + " " + identity);

        MyHistory myHistory = JSONObject.parseObject(message, MyHistory.class);
        if (myHistory != null) {
            myHistory.setCreateTime(LocalDateTime.now());
            if (identity.equals("u")) {
                if (sessionMap.get("t" + tid) != null)
                    myHistory.setReadStatus(1);
            } else {
                if (sessionMap.get("u" + uid) != null)
                    myHistory.setReadStatus(1);
            }
            myHistoryService.save(myHistory);
        }

//        List<MyHistory> myHistories = myHistoryService.selectMyHistory(myHistory);
        ArrayList<MyHistory> myHistories = new ArrayList<>();
        myHistories.add(myHistory);
        if (identity.equals("u")) {
            sendToOne("t" + tid, JSON.toJSONString(myHistories));
        } else {
            sendToOne("u" + uid, JSON.toJSONString(myHistories));
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("uid") String uid, @PathParam("tid") String tid, @PathParam("identity") String identity) {
        log.info("断开连接：" + uid + " " + tid + " " + identity);
        if (identity.equals("u"))
            sessionMap.remove("u" + uid);
        else
            sessionMap.remove("t" + tid);
    }

    /**
     * 单发
     *
     * @param userId 用户
     * @param message  消息
     */
    public void sendToOne(String userId, String message) {
        log.info("单发消息到：" + userId);
        if (sessionMap.get(userId) != null)
            sessionMap.get(userId).getAsyncRemote().sendText(message);
    }

    /**
     * 群发
     *
     * @param message
     */
    public void sendToAllClient(String message) {
        log.info("群发消息：" + message);
        Collection<Session> sessions = sessionMap.values();
        for (Session session : sessions) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
